In [1]:
from quimb import *
p0 = rand_ket(2**10)
h = ham_heis(10, sparse=True)
evo = Evolution(p0, h)
Update it in a single shot to a new time and get the state,
In [2]:
evo.update_to(1)
evo.pt
Out[2]:
Lazily generate the state at multiple times:
In [3]:
for pt in evo.at_times([2, 3, 4]):
print(expec(pt, p0))
In [4]:
p0 = rand_product_state(10)
h = ham_heis(10, sparse=True)
dims = [2] * 10
sysa, sysb = (0, 1), (2, 3)
def calc_t_and_logneg(t, pt):
ln = logneg_subsys(pt, dims, sysa, sysb)
return t, ln
evo = Evolution(p0, h, compute=calc_t_and_logneg, progbar=True)
evo.update_to(1)
ts, lns = zip(*evo.results)
In [5]:
ts
Out[5]:
In [6]:
lns
Out[6]:
In [7]:
def calc_t(t, _):
return t
def calc_logneg(_, pt):
return logneg_subsys(pt, [2]*10, 0, 1)
evo = Evolution(p0, h, compute={'t': calc_t, 'ln': calc_logneg}, progbar=True)
evo.update_to(1)
In [8]:
evo.results
Out[8]:
In [9]:
class MyTimeDepIsingHam:
def __init__(self, L):
self.h_interaction = ham_ising(L, sparse=True, jz=1.0, bx=0.0, cyclic=False)
self.h_field = ham_ising(L, sparse=True, jz=0.0, bx=1.0, cyclic=False)
def __call__(self, t):
return self.h_interaction + cos(t) * self.h_field
In [10]:
L = 16
# our initial state
psi0 = neel_state(L)
# instantiate the ham object, it's __call__ method will be used by Evolution
fn_ham_t = MyTimeDepIsingHam(L)
We still want to compute some properties during the evolution:
In [11]:
compute = {
'time': lambda t, p: t,
'entropy': lambda t, p: entropy_subsys(p, dims=[2] * L, sysa=range(L // 2))
}
Now we set up the evolution object again:
In [12]:
evo = Evolution(psi0, fn_ham_t, progbar=True, compute=compute)
In [13]:
evo.update_to(10)
We can plot the half chain entropy that we computed on the fly:
In [14]:
%matplotlib inline
from matplotlib import pyplot as plt
plt.plot(evo.results['time'], evo.results['entropy'])
Out[14]:
Or we can use the final state:
In [15]:
fidelity(psi0, evo.pt)
Out[15]: